package com.baizan.daka.util

import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import java.util.*

class FragmentStack(@IdRes val containerViewId: Int, val fm: FragmentManager) {

    /**
     * 当前显示的fragment name
     */
    private var cName: String? = null


    private val stack: HashMap<String, Fragment> = HashMap<String, Fragment>()


    fun containsFragemnt(f: String): Boolean {
        return stack.containsKey(f)
    }

    fun getFragment(f: String): Fragment? {
        return stack[f]
    }


    fun remove(replaced: String) {
        val ft: FragmentTransaction = fm.beginTransaction()
        val fragment = stack[replaced]
        if (fragment != null) {
            if (fragment.isAdded) {
                ft.remove(fragment).commitAllowingStateLoss()
            }
            stack.remove(replaced)
            cName = ""
        }
    }

    fun show(f: Fragment) {
        val fName: String = f.javaClass.name
        if (fName == cName) {
            return
        }
        val cMName = cName
        val cf = stack[fName]
        val ft: FragmentTransaction = fm.beginTransaction()
        if (stack[cMName] != null) {
            ft.hide(stack[cMName] as Fragment)
        }
        if (cf != null) {
            if (cf.isAdded) {
                ft.show(cf).commitAllowingStateLoss()
            } else {
                ft.add(containerViewId, f).commitAllowingStateLoss()
            }
        } else {
            ft.add(containerViewId, f).commitAllowingStateLoss()
            stack[fName] = f
        }
        cName = fName
    }

    fun hide() {
        if (cName == null) return
        val mName = cName
        val cf = stack[mName]
        val ft: FragmentTransaction = fm.beginTransaction()
        if (cf != null) {
            ft.hide(stack[mName] as Fragment).commitAllowingStateLoss()
        }
        cName = null
    }

    fun eixt() {
        val iterator: Iterator<Fragment> = stack.values.iterator()
        val ft: FragmentTransaction = fm.beginTransaction()
        while (iterator.hasNext()) {
            val fragment = iterator.next()
            ft.remove(fragment)
        }
        ft.commitAllowingStateLoss()
        stack.clear()
    }
}